/*
 * Copyright [2022] [https://www.xiaonuo.vip]
 *
 * Snowy采用APACHE LICENSE 2.0开源协议，您在使用过程中，需要注意以下几点：
 *
 * 1.请不要删除和修改根目录下的LICENSE文件。
 * 2.请不要删除和修改Snowy源码头部的版权声明。
 * 3.本项目代码可免费商业使用，商业使用请保留源码和相关描述文件的项目出处，作者声明等。
 * 4.分发源码时候，请注明软件出处 https://www.xiaonuo.vip
 * 5.不可二次分发开源参与同类竞品，如有想法可联系团队xiaonuobase@qq.com商议合作。
 * 6.若您的项目无法满足以上几点，需要更多功能代码，获取Snowy商业授权许可，请在官网购买授权，地址为 https://www.xiaonuo.vip
 */
package vip.xiaonuo.biz.modular.config.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vip.xiaonuo.biz.modular.action.entity.ReceiveAction;
import vip.xiaonuo.biz.modular.action.mapper.ReceiveActionMapper;
import vip.xiaonuo.biz.modular.algorithmConfig.entity.AlgorithmConfig;
import vip.xiaonuo.biz.modular.algorithmConfig.mapper.AlgorithmConfigMapper;
import vip.xiaonuo.biz.modular.config.param.*;
import vip.xiaonuo.biz.modular.config.util.DateUtil;
import vip.xiaonuo.biz.modular.config.util.HttpDreamLinkUtil;
import vip.xiaonuo.biz.modular.plan.entity.WeekPlan;
import vip.xiaonuo.biz.modular.plan.mapper.WeekPlanMapper;
import vip.xiaonuo.biz.modular.serverlog.entity.CallServerLog;
import vip.xiaonuo.biz.modular.serverlog.mapper.CallServerLogMapper;
import vip.xiaonuo.biz.modular.template.entity.ReceiveDeviceLog;
import vip.xiaonuo.biz.modular.template.entity.Template;
import vip.xiaonuo.biz.modular.template.entity.WeekTime;
import vip.xiaonuo.biz.modular.template.mapper.TemplateMapper;
import vip.xiaonuo.common.enums.CommonSortOrderEnum;
import vip.xiaonuo.common.exception.CommonException;
import vip.xiaonuo.common.page.CommonPageRequest;
import vip.xiaonuo.biz.modular.config.entity.DeviceConfig;
import vip.xiaonuo.biz.modular.config.mapper.DeviceConfigMapper;
import vip.xiaonuo.biz.modular.config.service.DeviceConfigService;
import vip.xiaonuo.common.util.CommonTimeFormatUtil;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.List;

/**
 * 算法配置Service接口实现类
 *
 * @author mengxiaowei
 * @date 2024/09/20 10:42
 **/
@Service
public class DeviceConfigServiceImpl extends ServiceImpl<DeviceConfigMapper, DeviceConfig> implements DeviceConfigService {

    @Resource
    private DeviceConfigMapper deviceConfigMapper;

    @Resource
    private WeekPlanMapper weekPlanMapper;

    @Resource
    private ReceiveActionMapper receiveActionMapper;

    @Resource
    private AlgorithmConfigMapper algorithmConfigMapper;


    @Resource
    private TemplateMapper templateMapper;

    @Resource
    private CallServerLogMapper callServerLogMapper;


    @Override
    public Page<DeviceConfig> page(DeviceConfigPageParam deviceConfigPageParam) {
        QueryWrapper<DeviceConfig> queryWrapper = new QueryWrapper<DeviceConfig>().checkSqlInjection();
        if (ObjectUtil.isAllNotEmpty(deviceConfigPageParam.getSortField(), deviceConfigPageParam.getSortOrder())) {
            CommonSortOrderEnum.validate(deviceConfigPageParam.getSortOrder());
            queryWrapper.orderBy(true, deviceConfigPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
                    StrUtil.toUnderlineCase(deviceConfigPageParam.getSortField()));
        } else {
            queryWrapper.lambda().orderByAsc(DeviceConfig::getSortCode);
        }
        return this.page(CommonPageRequest.defaultPage(), queryWrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(DeviceConfigAddParam deviceConfigAddParam) {
        DeviceConfig deviceConfig = BeanUtil.toBean(deviceConfigAddParam, DeviceConfig.class);
        this.save(deviceConfig);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(DeviceConfigEditParam deviceConfigEditParam) {
        DeviceConfig deviceConfig = this.queryEntity(deviceConfigEditParam.getId());
        BeanUtil.copyProperties(deviceConfigEditParam, deviceConfig);
        this.updateById(deviceConfig);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(List<DeviceConfigIdParam> deviceConfigIdParamList) {
        // 执行删除
        this.removeByIds(CollStreamUtil.toList(deviceConfigIdParamList, DeviceConfigIdParam::getId));
    }

    @Override
    public DeviceConfig detail(DeviceConfigIdParam deviceConfigIdParam) {
        return this.queryEntity(deviceConfigIdParam.getId());
    }

    @Override
    public DeviceConfig queryEntity(String id) {
        DeviceConfig deviceConfig = this.getById(id);
        if (ObjectUtil.isEmpty(deviceConfig)) {
            throw new CommonException("算法配置不存在，id值为：{}", id);
        }
        return deviceConfig;
    }

    @Override
    public void pushConfigure(PushConfigureParam pushConfigureParam) {

        List<DeviceConfig> deviceConfigList = this.list(new QueryWrapper<DeviceConfig>().eq("device_id", pushConfigureParam.getDeviceSn()));
        List<WeeklySchedule> weeklySchedules = pushConfigureParam.getWeeklySchedule();
        if (deviceConfigList.size() == 0) {
            DeviceConfig deviceConfig = new DeviceConfig();
            deviceConfig.setSwitchStatusSleep(pushConfigureParam.getSleepSwitchStatus());
            deviceConfig.setSwitchStatusWeek(pushConfigureParam.getWeekSwitchStatus());
            deviceConfig.setDeviceId(pushConfigureParam.getDeviceSn());
            deviceConfig.setUserId(pushConfigureParam.getUserId());
            deviceConfigMapper.insert(deviceConfig);

            for (int i = 0; i < weeklySchedules.size(); i++) {
                WeekPlan weekPlan = new WeekPlan();
                BeanUtil.copyProperties(pushConfigureParam.getWeeklySchedule().get(i), weekPlan);
                weekPlan.setDeviceConfigId(deviceConfig.getId());
                weekPlanMapper.insert(weekPlan);

            }
        } else {
            DeviceConfig deviceConfig = new DeviceConfig();
            deviceConfig.setSwitchStatusSleep(pushConfigureParam.getSleepSwitchStatus());
            deviceConfig.setSwitchStatusWeek(pushConfigureParam.getWeekSwitchStatus());
            deviceConfig.setDeviceId(pushConfigureParam.getDeviceSn());
            deviceConfig.setId(deviceConfigList.get(0).getId());
            deviceConfigMapper.updateById(deviceConfig);
            weekPlanMapper.deleteByDeviceId(deviceConfigList.get(0).getId());

            for (int i = 0; i < weeklySchedules.size(); i++) {
                WeekPlan weekPlan = new WeekPlan();
                BeanUtil.copyProperties(pushConfigureParam.getWeeklySchedule().get(i), weekPlan);
                weekPlan.setDeviceConfigId(deviceConfigList.get(0).getId());
                weekPlanMapper.insert(weekPlan);

            }


        }


    }


    @Override
    public void receiveDeviceEvent(DeviceEventParam deviceEventParam) throws IOException {
        ReceiveAction receiveAction = new ReceiveAction();
        receiveAction.setUserId(deviceEventParam.getUserId());
        DeviceEventParam.RadioDTO radioDTO = deviceEventParam.getRadio();
        if (radioDTO != null) {
            receiveAction.setActionEvent(radioDTO.getEvt());
            receiveAction.setReceiveTime(radioDTO.getTimestamp());
            receiveActionMapper.insert(receiveAction);
        }

        /*List<DeviceConfig> deviceConfigList = deviceConfigMapper.selectList(new QueryWrapper<DeviceConfig>().eq("user_id", deviceEventParam.getUserId()));
        LocalDate today = LocalDate.now();
        DayOfWeek dayOfWeek = today.getDayOfWeek();
        List<WeekPlan> weekPlanList = weekPlanMapper.selectList(new QueryWrapper<WeekPlan>().
                eq("device_config_id", deviceConfigList.get(0).getId()).eq("day", dayOfWeek.getValue()));

        long start = CommonTimeFormatUtil.TimeToStamp(weekPlanList.get(0).getStartTime());
        long end = CommonTimeFormatUtil.TimeToStamp(weekPlanList.get(0).getEndTime());

        DeviceServer deviceServer = new DeviceServer();
        DeviceServer.CmdDTO cmdDTO = new DeviceServer.CmdDTO();
        DeviceServer.CmdDTO.ProcessDTO processDTO = new DeviceServer.CmdDTO.ProcessDTO();
        processDTO.setAmp(10);
        processDTO.setDuration(10);
        processDTO.setFrq(10);
        processDTO.setMode("pwm");
        cmdDTO.setServer("audio");
        cmdDTO.setProcess(processDTO);
        deviceServer.setUserId(1111);
        deviceServer.setCmd(cmdDTO);


        if (deviceConfigList.size() > 0 && weekPlanList.size() > 0) {
            if (deviceConfigList.get(0).getSwitchStatusSleep() == 1 && deviceConfigList.get(0).getSwitchStatusWeek() == 1) {

                DeviceEventParam.MainDTO mainDTO = deviceEventParam.getMain();
                DeviceEventParam.EEGtESDTO eeGt = deviceEventParam.getEEGtES();
                *//*DeviceEventParam.RadioDTO radioDTO = deviceEventParam.getRadio();

                if (mainDTO.getTimestamp() > start && mainDTO.getTimestamp() < end) {
                    //todo
                    CommonHttp.http(JSONUtil.toJsonStr(deviceServer),"");

                }
                if (eeGt.getTimestamp() > start && eeGt.getTimestamp() < end) {
                    CommonHttp.http(JSONUtil.toJsonStr(deviceServer),"");

                }
                if (radioDTO.getTimestamp() > start && radioDTO.getTimestamp() < end) {
                    CommonHttp.http(JSONUtil.toJsonStr(deviceServer),"");
                }*//*


            }


        }*/

    }


    @Override
    public void scheduledTasks() throws Exception {


        Calendar calendar = Calendar.getInstance();
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);

        //助眠
        List<Template> templateListSleep = templateMapper.selectList(new QueryWrapper<Template>()
                .eq("template_type", 1));


        //唤醒
        List<Template> templateListWake = templateMapper.selectList(new QueryWrapper<Template>()
                .eq("template_type", 2));


        //唤醒---一个时间
        if (templateListWake.size() > 0) {
            String slot = templateListWake.get(0).getTimeSlot();
            String triggerMode = templateListWake.get(0).getTriggerMode();
            List<WeekTime> weekTimeList = templateMapper.selectEndTime(DateUtil.week(dayOfWeek));
            for (WeekTime weekTime : weekTimeList) {
                String cmdTime = CommonTimeFormatUtil.computingTime(weekTime.getEndTime(), Integer.parseInt(slot), triggerMode);
                LocalDateTime now = LocalDateTime.now();
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm");
                String currentTimeString = now.format(formatter);
                //long a = CommonTimeFormatUtil.timeDifference(currentTimeString, cmdTime);
                if (currentTimeString.equals(cmdTime)) {
                    CallServerLog callServerLog = new CallServerLog();
                    callServerLog.setName("调用第三方平台--唤醒");
                    callServerLog.setUrl("http://127.0.0.1:8080/api/v1/callServerLog/callServerLog");
                    callServerLogMapper.insert(callServerLog);

                    QueryWrapper<AlgorithmConfig> queryWrapper = new QueryWrapper<>();
                    queryWrapper.eq("template_id", templateListWake.get(0).getId());
                    List<AlgorithmConfig> algorithmConfigList = algorithmConfigMapper.selectList(queryWrapper);

                    HttpDreamLinkUtil.httpDreamLink(algorithmConfigList, weekTimeList.get(0).getDeviceId());


                }
            }


        }


        if (templateListSleep.size() > 0) {
            String slot = templateListSleep.get(0).getTimeSlot();
            String triggerMode = templateListSleep.get(0).getTriggerMode();
            String sleepTime = "";
            ReceiveDeviceLog bedTime = templateMapper.selectBedTime();
            List<WeekTime> weekTimes = templateMapper.selectStartTime(DateUtil.week(dayOfWeek));

            for (int i = 0; i < weekTimes.size(); i++) {
               /* if (bedTime == null) {

                }*/


                //助眠提前
                //if (triggerMode.equals("1")) {
                sleepTime = weekTimes.get(i).getStartTime();
                // }
                //助眠延后
                /*if (triggerMode.equals("2") && bedTime != null) {

                    sleepTime = bedTime.getReceiveTime();

                }*/


                String cmdTime = CommonTimeFormatUtil.computingTime(sleepTime, Integer.parseInt(slot), triggerMode);
                LocalDateTime now = LocalDateTime.now();
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm");
                String currentTimeString = now.format(formatter);
                //long a = CommonTimeFormatUtil.timeDifference(currentTimeString, cmdTime);
                if (currentTimeString.equals(cmdTime)) {
                    CallServerLog callServerLog = new CallServerLog();
                    callServerLog.setName("调用第三方平台--助眠");
                    callServerLog.setUrl("http://127.0.0.1:8080/api/v1/callServerLog/callServerLog");
                    callServerLogMapper.insert(callServerLog);


                    ReceiveAction receiveAction = new ReceiveAction();
                    receiveAction.setId(bedTime.getId());
                    receiveAction.setStatus("2");
                    receiveActionMapper.updateById(receiveAction);

                    QueryWrapper<AlgorithmConfig> queryWrapper = new QueryWrapper<>();
                    queryWrapper.eq("templateId", templateListWake.get(0).getId());
                    List<AlgorithmConfig> algorithmConfigList = algorithmConfigMapper.selectList(queryWrapper);

                    HttpDreamLinkUtil.httpDreamLink(algorithmConfigList, weekTimes.get(i).getDeviceId());


                }
            }


        }


    }


}
